package com.example.common.advice;


import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;

import com.example.common.result.ResponseCode;
import com.example.common.result.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
 * 全局异常拦截 返回json数据响应
 * 使用RestControllerAdvice注解 即可将异常以JSON数据的形式传递给前端 其实就是 Responsebody 与 ControllerAdvice 的结合
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionErrorHandler {


    /** 动态库不存在 */
    @ExceptionHandler(UnsatisfiedLinkError.class)
    public ResponseResult unsatisfiedLinkError(UnsatisfiedLinkError ex) {
        log.error("动态库不存在：{}", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.ERROR_UNSATISFIEDLINK);
    }

    /** 运行时异常 */
    @ExceptionHandler(RuntimeException.class)
    public ResponseResult runtimeExceptionHandler(RuntimeException ex) {
        log.error("运行时异常：{}", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_RUNTIME);
    }

    /** 空指针异常 */
    @ExceptionHandler(NullPointerException.class)
    public ResponseResult nullPointerExceptionHandler(NullPointerException ex) {
        log.error("空指针异常：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_NULL_POINTER);
    }

    /** 类型转换异常 */
    @ExceptionHandler(ClassCastException.class)
    public ResponseResult classCastExceptionHandler(ClassCastException ex) {
        log.error("类型转换异常：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_CLASS_CAST);
    }
    /** 文件未找到异常 */
    @ExceptionHandler(FileNotFoundException.class)
    public ResponseResult FileNotFoundException(FileNotFoundException ex) {
        log.error("文件未找到异常：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_FILE_NOT_FOUND);
    }
    /** 数字格式异常 */
    @ExceptionHandler(NumberFormatException.class)
    public ResponseResult NumberFormatException(NumberFormatException ex) {
        log.error("数字格式异常：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_NUMBER_FORMAT);
    }
    /** 安全异常 */
    @ExceptionHandler(SecurityException.class)
    public ResponseResult SecurityException(SecurityException ex) {
        log.error("Security安全异常(如果安全管理器存在并且其 checkLink 方法不允许加载指定的动态库)：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_SECURITY);
    }
    /** sql异常 */
    @ExceptionHandler(SQLException.class)
    public ResponseResult SQLException(SQLException ex) {
        log.error("sql异常：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_SQL);
    }
    /** 类型不存在异常 */
    @ExceptionHandler(TypeNotPresentException.class)
    public ResponseResult TypeNotPresentException(TypeNotPresentException ex) {
        log.error("类型不存在异常：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_TYPE_NOT_PRESENT);
    }

    /** IO异常 */
    @ExceptionHandler(IOException.class)
    public ResponseResult iOExceptionHandler(IOException ex) {
        log.error("IO异常：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_IO);
    }

    /** 未知方法异常 */
    @ExceptionHandler(NoSuchMethodException.class)
    public ResponseResult noSuchMethodExceptionHandler(NoSuchMethodException ex) {
        log.error("未知方法异常：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_NO_SUCH_METHOD);
    }

    /** 数组越界异常 */
    @ExceptionHandler(IndexOutOfBoundsException.class)
    public ResponseResult indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
        log.error("数组越界异常：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_INDEX_OUT_OF_BOUNDS);
    }

    /** sql语法错误异常
    @ExceptionHandler(BadSqlGrammarException.class)
    public ResponseResult BadSqlGrammarException(BadSqlGrammarException ex) {
        log.error("sql语法错误异常：{} ", ex.getMessage(), ex);
        result.setMessage("空指针异常!");
        return new ResponseResult(ResponseCode.EXCEPTION);
    } */

    /** 无法注入bean异常 */
    @ExceptionHandler(NoSuchBeanDefinitionException.class)
    public ResponseResult noSuchBeanDefinitionException(NoSuchBeanDefinitionException ex) {
        log.error("无法注入bean异常 ：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_NO_SUCH_BEAN_DEFINITION);
    }


    /** 除数不能为0 */
    @ExceptionHandler({ArithmeticException.class})
    public ResponseResult arithmeticException(ArithmeticException ex) {
        log.error("除数不能为0：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_ARITHMETIC);
    }

    /** 其他异常 */
    @ExceptionHandler({Exception.class})
    public ResponseResult exception(Exception ex) {
        if(ex.getMessage().indexOf("java.lang.UnsatisfiedLinkError") > 0){
            log.error("动态库不存在：{}", ex.getMessage(), ex);
            return new ResponseResult(ResponseCode.ERROR_UNSATISFIEDLINK);
        }else{
             log.error("服务器异常，其他错误：{} ", ex.getMessage(), ex);
            return new ResponseResult(ResponseCode.EXCEPTION);
        }
    }

    /** http type错误 */
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public ResponseResult httpType(HttpRequestMethodNotSupportedException ex) {
        log.error("http type：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_HTTP_TYPE);
    }


    /** 400错误 */
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public ResponseResult requestNotReadable(HttpMessageNotReadableException ex) {
        log.error("400错误..requestNotReadable：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_HTTP_400);
    }

    /** 400错误 */
    @ExceptionHandler({TypeMismatchException.class})
    public ResponseResult requestTypeMismatch(TypeMismatchException ex) {
        log.error("400错误..TypeMismatchException：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_HTTP_400);
    }

    /** 500错误 */
    @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
    public ResponseResult server500(RuntimeException ex) {
        log.error("500错误：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.EXCEPTION_HTTP_500);
    }




    /** 栈溢出 */
    @ExceptionHandler({StackOverflowError.class})
    public ResponseResult requestStackOverflow(StackOverflowError ex) {
        log.error("栈溢出：{} ", ex.getMessage(), ex);
        return new ResponseResult(ResponseCode.ERROR_STACK_OVERFLOW);
    }

}
